package com.purchase.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.purchase.entity.Goods;
import com.purchase.entity.GoodsStock;
import com.purchase.mapper.CartMapper;
import com.purchase.mapper.GoodsMapper;
import com.purchase.mapper.GoodsStockMapper;
import com.purchase.mapper.OrderMapper;
import com.purchase.service.OrderService;
import com.purchase.util.LogInfo;
import com.purchase.util.OrderIdGenerater;
import com.purchase.util.RequestForm;
import com.purchase.util.ResponseForm;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.crypto.hash.Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    OrderMapper orderMapper;

    @Autowired
    CartMapper cartMapper;

    @Autowired
    GoodsMapper goodsMapper;

    @Autowired
    GoodsStockMapper goodsStockMapper;

    @Override
    public ResponseForm getOrderListByStatus(RequestForm param) {
        ResponseForm result = new ResponseForm();
        Map<String, Object> paramMap = (Map<String, Object>) param.getData();
        try {
            String userId = (String) paramMap.get("userId");
            if (!StringUtils.isNotBlank(userId)) {
                result.setStatus(false);
                result.setMessage(LogInfo.PARAM_ERROR);
                log.error(LogInfo.PARAM_ERROR);
                return result;
            }

            //获取订单列表
            com.purchase.util.Page.parsePage(paramMap);
            Page<Object> pageHelper = PageHelper.startPage((int) paramMap.get("page"), (int) paramMap.get("size"));
            List<Map<String, Object>> list = orderMapper.getOrderByStatus(paramMap);
            for (Map<String, Object> map : list) {
                List<String> pics = orderMapper.getOrderDetailPicListByOrderId(String.valueOf(map.get("id")));
                map.put("pics", pics);
            }
            result.setData(list);
            result.setTotal((int) pageHelper.getTotal());
        } catch (Exception e) {
            e.printStackTrace();
            result.setStatus(false);
            result.setMessage(LogInfo.ERROR);
            log.error(LogInfo.ERROR);
        }
        return result;
    }

    @Override
    public ResponseForm getOrderDetailList(RequestForm param) {
        ResponseForm result = new ResponseForm();
        Map<String, Object> paramMap = (Map<String, Object>) param.getData();
        try {
            String orderId = (String) paramMap.get("orderId");
            String storeNo = (String) paramMap.get("storeNo");
            if (!StringUtils.isNotBlank(orderId) || !StringUtils.isNotBlank(storeNo)) {
                result.setStatus(false);
                result.setMessage(LogInfo.PARAM_ERROR);
                log.error(LogInfo.PARAM_ERROR);
                return result;
            }
            //返回订单详情列表
            List<Map<String, Object>> list = orderMapper.getOrderDetailListByOrderId(orderId);

            //订单信息
            Map<String, Object> order = orderMapper.getOrderByIdAndStoreNo(orderId, storeNo);
            HashMap<String, Object> dataMap = new HashMap<>();
            dataMap.put("list", list);
            dataMap.put("orderId", String.valueOf(order.get("id")));
            dataMap.put("userId", String.valueOf(order.get("user_id")));
            dataMap.put("orderPrice", String.valueOf(order.get("price")));
            dataMap.put("orderGoodsNum", String.valueOf(order.get("goods_num")));
            dataMap.put("createTime", t2d((Timestamp) order.get("create_time")));
            dataMap.put("updateTime", t2d((Timestamp) order.get("update_time")));
            dataMap.put("orderStatus", String.valueOf(order.get("order_status")));
            dataMap.put("logisticStatus", String.valueOf(order.get("logistic_status")));
            dataMap.put("postage", String.valueOf(order.get("postage")));
            dataMap.put("userAddressId", String.valueOf(order.get("user_adress_id") == null ? "" : order.get("user_adress_id")));
            result.setData(dataMap);
        } catch (Exception e) {
            e.printStackTrace();
            result.setStatus(false);
            result.setMessage(LogInfo.ERROR);
            log.error(LogInfo.ERROR);
        }
        return result;
    }

    @Override
    public ResponseForm updateOrderIsDelete(RequestForm param) {
        ResponseForm result = new ResponseForm();
        Map<String, Object> paramMap = (Map<String, Object>) param.getData();
        try {
            String orderId = (String) paramMap.get("orderId");
            if (!StringUtils.isNotBlank(orderId)) {
                result.setStatus(false);
                result.setMessage(LogInfo.PARAM_ERROR);
                log.error(LogInfo.PARAM_ERROR);
                return result;
            }

            orderMapper.updateOrderIsDeleteByOrderId(paramMap);
        } catch (Exception e) {
            e.printStackTrace();
            result.setStatus(false);
            result.setMessage(LogInfo.ERROR);
            log.error(LogInfo.ERROR);
        }
        return result;
    }

    @Override
    public ResponseForm updateOrderAddress(RequestForm param) {
        ResponseForm result = new ResponseForm();
        Map<String, Object> paramMap = (Map<String, Object>) param.getData();
        try {
            String orderId = (String) paramMap.get("orderId");
            String userAddressId = (String) paramMap.get("userAddressId");
            if (!StringUtils.isNotBlank(orderId)
                    || !StringUtils.isNotBlank(userAddressId)) {
                result.setStatus(false);
                result.setMessage(LogInfo.PARAM_ERROR);
                log.error(LogInfo.PARAM_ERROR);
                return result;
            }

            orderMapper.updateOrderAddress(paramMap);
        } catch (Exception e) {
            e.printStackTrace();
            result.setStatus(false);
            result.setMessage(LogInfo.ERROR);
            log.error(LogInfo.ERROR);
        }
        return result;
    }

    /**
     * 1. 购物车内商品 -> 订单
     * 2. 解析购物车list，循环list放入orderId再放入订单详情，计算订单金额
     * 3. 入库订单详情
     * 4. 订单价格根据数据库内订单详情计算
     * 5. 入库订单
     * 6. 删除购物车
     * 7. 返回订单详情list
     *
     * @param param
     * @return
     */
    @Transactional
    @Override
    public ResponseForm createOrderAndDetailsFromCart(RequestForm param) {
        ResponseForm result = new ResponseForm();
        Map<String, Object> paramMap = (Map<String, Object>) param.getData();
        try {
            //接收前端购物车json
            List<Map<String, Object>> cartMapList = (List<Map<String, Object>>) paramMap.get("list");

            List<Map<String, Object>> cartDbList = cartMapper.getCartListByUserIdStoreNoGoodsIdSpecsName(cartMapList);
            if (cartDbList == null) {
                throw new Exception();
            }

            //生成订单号
            String orderId = OrderIdGenerater.generateOrderId();

            String userId = (String) cartMapList.get(0).get("userId");
            String storeNo = (String) cartMapList.get(0).get("storeNo");
            int orderGoodsNum = 0;
            Double orderPrice = 0.00;
            //解析购物车list，循环list放入orderId再放入订单详情，计算订单金额
            for (Map<String, Object> map : cartDbList) {
                map.put("orderId", orderId);
                orderGoodsNum = (int) map.get("goodsNum") + orderGoodsNum;
                orderPrice = (Double) map.get("goodsPrice") * (int) map.get("goodsNum") + orderPrice;
                //删除购物车
                cartMapper.deleteGoodsInCart(map);
            }

            Map<String, Object> userAddressIdAndPostage = orderMapper.getUserAddressIdAndPostageByUserId(userId, storeNo);
            //组装订单
            HashMap<String, Object> orderMap = new HashMap<>();
            orderMap.put("id", orderId);
            orderMap.put("userId", userId);
            orderMap.put("price", orderPrice);
            orderMap.put("goodsNum", orderGoodsNum);
            orderMap.put("storeNo", storeNo);
            orderMap.put("postage", userAddressIdAndPostage.get("postage"));
            orderMap.put("userAddressId", userAddressIdAndPostage.get("userAddressId"));

            //订单和详情入库
            orderMapper.createOrder(orderMap);
            log.info("订单入库,订单号={}", orderId);
            orderMapper.createOrderDetails(cartDbList);
            log.info("订单详情入库");

            HashMap<String, Object> dataMap = new HashMap<>();
            dataMap.put("orderId", orderId);
            dataMap.put("orderPrice", String.valueOf(orderPrice));
            dataMap.put("orderGoodsNum", String.valueOf(orderGoodsNum));
            result.setData(dataMap);
        } catch (Exception e) {
            e.printStackTrace();
            result.setStatus(false);
            result.setMessage(LogInfo.ERROR);
            log.error(LogInfo.ERROR);
        }
        return result;
    }

    /**
     * 立即抢购
     * <p>
     * 1. 商品 -> 订单
     * 2. 查询商品信息 -> 订单详情，计算订单金额
     * 3. 入库订单详情
     * 4. 订单价格根据数据库内订单详情计算
     * 5. 入库订单
     * 7. 返回订单详情list
     *
     * @param param
     * @return
     */
    @Override
    public ResponseForm createOrderAndDetailsRightNow(RequestForm param) {
        ResponseForm result = new ResponseForm();
        Map<String, Object> paramMap = (Map<String, Object>) param.getData();
        try {
            String userId = (String) paramMap.get("userId");
            String storeNo = (String) paramMap.get("storeNo");
            String goodsId = (String) paramMap.get("goodsId");
            String goodsNum = (String) paramMap.get("goodsNum");
            String goodsPrice = (String) paramMap.get("goodsPrice");
            String specsName = (String) paramMap.get("specsName");
            String goodsPic = (String) paramMap.get("goodsPic");
            String goodsName = (String) paramMap.get("goodsName");
            String goodsColor = (String) paramMap.get("goodsColor");
            if (!StringUtils.isNotBlank(userId)
                    || !StringUtils.isNotBlank(userId)
                    || !StringUtils.isNotBlank(storeNo)
                    || !StringUtils.isNotBlank(goodsId)
                    || !StringUtils.isNotBlank(goodsNum)
                    || !StringUtils.isNotBlank(goodsPrice)
                    || !StringUtils.isNotBlank(specsName)
                    || !StringUtils.isNotBlank(goodsName)
                    || !StringUtils.isNotBlank(goodsColor)
                    || !StringUtils.isNotBlank(goodsPic)) {
                result.setStatus(false);
                result.setMessage(LogInfo.PARAM_ERROR);
                log.error(LogInfo.PARAM_ERROR);
                return result;
            }

            //生成订单号
            String orderId = OrderIdGenerater.generateOrderId();

            //获取商品详情
            Goods goods = new Goods();
            goods.setGoodsId(Integer.valueOf(goodsId));
            goods = goodsMapper.selectOne(goods);
            HashMap<String, Object> detailMap = new HashMap<>();
            detailMap.put("orderId", orderId);
            detailMap.put("goodsName", goods.getGoodsName());
            detailMap.put("goodsPic", goods.getGoodsPic());
            detailMap.put("goodsNum", goodsNum);
            detailMap.put("goodsPrice", goods.getDiscountPrice());
            detailMap.put("originalPrice", goods.getGoodsPrice());
            detailMap.put("goodsId", goods.getGoodsId());
            detailMap.put("specsName", specsName);
            List<Map<String, Object>> detailList = new ArrayList<>();
            detailList.add(detailMap);

            Double orderPrice = goods.getDiscountPrice().doubleValue() * Integer.valueOf(goodsNum);

            Map<String, Object> userAddressIdAndPostage = orderMapper.getUserAddressIdAndPostageByUserId(userId, storeNo);
            //组装订单
            HashMap<String, Object> orderMap = new HashMap<>();
            orderMap.put("id", orderId);
            orderMap.put("userId", userId);
            orderMap.put("price", orderPrice);
            orderMap.put("goodsNum", goodsNum);
            orderMap.put("storeNo", storeNo);
            orderMap.put("postage", userAddressIdAndPostage.get("postage"));
            orderMap.put("userAddressId", userAddressIdAndPostage.get("userAddressId"));

            //订单和详情入库
            orderMapper.createOrder(orderMap);
            log.info("订单入库,订单号={}", orderId);
            orderMapper.createOrderDetails(detailList);
            log.info("订单详情入库");

            HashMap<String, Object> dataMap = new HashMap<>();
            dataMap.put("orderId", orderId);
            dataMap.put("orderPrice", String.valueOf(orderPrice));
            dataMap.put("orderGoodsNum", goodsNum);
            result.setData(dataMap);
        } catch (Exception e) {
            e.printStackTrace();
            result.setStatus(false);
            result.setMessage(LogInfo.ERROR);
            log.error(LogInfo.ERROR);
        }
        return result;
    }

    @Override
    public ResponseForm getOrderCountByUserId(RequestForm param) {

        ResponseForm result = new ResponseForm();
        Map<String, Object> paramMap = (Map<String, Object>) param.getData();
        try {
            String userId = (String) paramMap.get("userId");
            if (!StringUtils.isNotBlank(userId)) {
                result.setStatus(false);
                result.setMessage(LogInfo.PARAM_ERROR);
                log.error(LogInfo.PARAM_ERROR);
                return result;
            }

            //获取不同状态订单数量
            Map<String, Object> count = orderMapper.getOrderCountByUserId(userId);

            Map<Object, Object> resultMap = new HashMap<>();
            resultMap.put("allCount", count.get("allCount"));
            resultMap.put("waitPayCount", count.get("waitPayCount"));
            resultMap.put("logicWaitCount", count.get("logicWaitCount"));
            result.setData(resultMap);
        } catch (Exception e) {
            e.printStackTrace();
            result.setStatus(false);
            result.setMessage(LogInfo.ERROR);
            log.error(LogInfo.ERROR);
        }
        return result;

    }

    @Override
    public synchronized ResponseForm updateOrderLogisticStatus(RequestForm param) {
        ResponseForm result = new ResponseForm();
        Map<String, Object> paramMap = (Map<String, Object>) param.getData();
        try {
            String orderId = (String) paramMap.get("orderId");
            String logisticStatus = (String) paramMap.get("logisticStatus");
            if (!StringUtils.isNotBlank(orderId) || !StringUtils.isNotBlank(logisticStatus)) {
                result.setStatus(false);
                result.setMessage(LogInfo.PARAM_ERROR);
                log.error(LogInfo.PARAM_ERROR);
                return result;
            }

            orderMapper.updateOrderStatusById(paramMap);
        } catch (Exception e) {
            e.printStackTrace();
            result.setStatus(false);
            result.setMessage(LogInfo.ERROR);
            log.error(LogInfo.ERROR);
        }
        return result;
    }

    @Override
    public ResponseForm updateDetailRefundFlag(RequestForm param) {
        ResponseForm result = new ResponseForm();
        Map<String, Object> paramMap = (Map<String, Object>) param.getData();
        try {
            String orderDetailsId = (String) paramMap.get("orderDetailsId");
            String refundFlag = (String) paramMap.get("refundFlag");
            if (!StringUtils.isNotBlank(orderDetailsId) || !StringUtils.isNotBlank(refundFlag)) {
                result.setStatus(false);
                result.setMessage(LogInfo.PARAM_ERROR);
                log.error(LogInfo.PARAM_ERROR);
                return result;
            }

            orderMapper.updateDetailRefundFlagByDetailsId(paramMap);
        } catch (Exception e) {
            e.printStackTrace();
            result.setStatus(false);
            result.setMessage(LogInfo.ERROR);
            log.error(LogInfo.ERROR);
        }
        return result;
    }

    @Override
    public ResponseForm getOrderByStatusAndStoreNo(RequestForm param) {
        ResponseForm result = new ResponseForm();
        Map<String, Object> paramMap = (Map<String, Object>) param.getData();
        try {
            String roleId = (String) paramMap.get("roleId");
            String storeNo = (String) paramMap.get("storeNo");

            if ("2".equals(roleId)) {
                paramMap.remove("storeNo");
            }

            //获取订单列表
            com.purchase.util.Page.parsePage(paramMap);
            Page<Object> pageHelper = PageHelper.startPage((int) paramMap.get("page"), (int) paramMap.get("size"));
            List<Map<String, Object>> list = orderMapper.getOrderByStatusAndStoreNo(paramMap);
            result.setData(list);
            result.setTotal((int) pageHelper.getTotal());
        } catch (Exception e) {
            e.printStackTrace();
            result.setStatus(false);
            result.setMessage(LogInfo.ERROR);
            log.error(LogInfo.ERROR);
        }
        return result;
    }

    @Override
    public ResponseForm createLogistics(RequestForm param) {
        ResponseForm result = new ResponseForm();
        Map<String, Object> paramMap = (Map<String, Object>) param.getData();
        try {
            String orderId = (String) paramMap.get("orderId");
            String logisticsName = (String) paramMap.get("logisticsName");
            String logisticsNo = (String) paramMap.get("logisticsNo");
            if (!StringUtils.isNotBlank(orderId)
                    || !StringUtils.isNotBlank(logisticsName)
                    || !StringUtils.isNotBlank(logisticsNo)) {
                result.setStatus(false);
                result.setMessage(LogInfo.PARAM_ERROR);
                log.error(LogInfo.PARAM_ERROR);
                return result;
            }

            orderMapper.insertLogistics(paramMap);
        } catch (Exception e) {
            e.printStackTrace();
            result.setStatus(false);
            result.setMessage(LogInfo.ERROR);
            log.error(LogInfo.ERROR);
        }
        return result;
    }

    @Override
    public ResponseForm getLogistics(RequestForm param) {
        ResponseForm result = new ResponseForm();
        Map<String, Object> paramMap = (Map<String, Object>) param.getData();
        try {
            String orderId = (String) paramMap.get("orderId");
            if (!StringUtils.isNotBlank(orderId)) {
                result.setStatus(false);
                result.setMessage(LogInfo.PARAM_ERROR);
                log.error(LogInfo.PARAM_ERROR);
                return result;
            }

            Map<String, Object> map = orderMapper.getLogistics(paramMap);
            result.setData(map);
        } catch (Exception e) {
            e.printStackTrace();
            result.setStatus(false);
            result.setMessage(LogInfo.ERROR);
            log.error(LogInfo.ERROR);
        }
        return result;
    }

    @Override
    public ResponseForm reduceGoodsStock(RequestForm param) {
        ResponseForm result = new ResponseForm();
        Map<String, Object> paramMap = (Map<String, Object>) param.getData();
        try {
            String orderId = (String) paramMap.get("orderId");
            if (!StringUtils.isNotBlank(orderId)) {
                result.setStatus(false);
                result.setMessage(LogInfo.PARAM_ERROR);
                log.error(LogInfo.PARAM_ERROR);
                return result;
            }

            //根据订单id查订单详情
            List<Map<String, Object>> detailList = orderMapper.getOrderDetailListByOrderId(orderId);
            for (Map<String, Object> detailMap : detailList) {
                int stockNum = (int) detailMap.get("stock_num");
                int goodsNum = (int) detailMap.get("goods_num");
                int goodsId = (int) detailMap.get("goods_id");
                String specsName = (String) detailMap.get("specs_name");

                //更新商品库存
                GoodsStock goodsStock = new GoodsStock();
                goodsStock.setStockNum(stockNum - goodsNum);
                Example example = new Example(GoodsStock.class);
                Example.Criteria criteria = example.createCriteria();
                criteria.andEqualTo("goodsId", goodsId);
                criteria.andEqualTo("specsName", specsName);
                goodsStockMapper.updateByExampleSelective(goodsStock, example);
            }
        } catch (Exception e) {
            e.printStackTrace();
            result.setStatus(false);
            result.setMessage(LogInfo.ERROR);
            log.error(LogInfo.ERROR);
        }
        return result;
    }

    /**
     * 时间戳转换成日期格式字符串
     *
     * @param seconds 精确到秒的字符串
     * @return
     */
    public String t2d(Timestamp seconds) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return format.format(seconds);
    }

}
